#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <unistd.h>

#include "../include/common.h"
#include "../include/split.h"

int
split(void *(*func)(void*), void *pars, void *tf, char s, void (handlerF)(int))
{
    int *f = NULL;
    pthread_t *t = NULL;

    if (func == NULL || tf == NULL)
        return 0;

    switch(s)
    {
        case 'f':
            f = (int *)tf;
            *f = fork();
            switch ( *f )
            {
                case -1:
                    fatal ("fork call");
                    exit(1);
                    break;

                /* child */
                case 0:
                    /* Signals for child */
                    (void)signal(SIGINT, noSIGINT);

                    if (handlerF != NULL)
                        (void)signal(SIGUSR1, handlerF);

                    func(pars);
                    exit (0);
                    break;

                /* parent */
                default:
                    return 1;
            }

            break;

        case 't':
            t = (pthread_t *)tf;
            if (pthread_create(t, NULL, func, pars) != 0)
            {
                fatal ("thread call");
                exit(1);
            }
            break;

        default:
            return 0;
            break;
    }

    return 1;
}

void
exitSplit(char s)
{
    switch(s)
    {
        case 'f':
            exit(0);

            break;

        case 't':
            pthread_exit(NULL);
            break;

        default:
            break;
    }
}

void
waitSplits(pthread_t *t, int cant, char s)
{
    int i, stat;

    switch(s)
    {
        case 'f':
            while ((waitpid (-1, &stat, 0)) > 0);

            break;

        case 't':
            if (t != NULL)
                for( i = 0 ; i < cant ; i++ )
                    pthread_join(t[i], NULL);

            break;

        default:
            break;
    }

}

void
noSIGINT(int signo)
{
    return;
}
